#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Purpose: Text export for HydroPlatform
# Created: 08/26/2009
# $Id $
# Copyright (c) 2008,2009 by University College London
# Authors:
#  Didrik Pinte <dpinte@dipole-consulting.com>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with HydroPlatform for details.

import codecs
from itertools import count, chain
import logging
import numpy
import os
import sets
import datetime

from sqlalchemy import and_

from hydroplatform.model.export import Exporter, ExportError, ExporterRegistry
from hydroplatform.model import network as nt
from hydroplatform.model import fields as fd
from hydroplatform.model import units

MAX_LEN = 31

# This class exports the entire network into a single XML file. 
# The intention of this is the easy visualisation of data if needed. This will hopefully 
# allow the user to export their data, and edit it with an XML GUI editor (Yigal Irani 
# has give us permission to package and distribute his 'XML Marker'), before importing it 
# back into the project with all the modified data values. 

# There should be a message to notify the users that the id field should not be modified.
# Perhaps it would be wise to give each object a scrambled identifier that looks too scary
# for users to edit.

class XMLExport(Exporter):
    '''
    Exports network to single XML file
    '''
    _name = "XML exporter"
    _description  = '''Exports a network to a single XML file '''
    
    def __init__(self):
        Exporter.__init__(self)
        self.session = None    
        
    def export(self, network, filename, session=None):
        '''
        Export the given network to a set of files
        '''
        import pdb; pdb.set_trace()
        def get_field_type(field):
          '''
          Returns a string with the type of field
          '''

          if isinstance(field.attribute_type, fd.Parameter):
            return "Parameter"
          elif isinstance(field.attribute_type, fd.TimeSerie):
            return "Time_Series"
          elif isinstance(field.attribute_type, fd.NodeReferences):
            return "Node_Refereces"
          elif isinstance(field.attribute_type, fd.LinkReferences):
            return "Link_References"
          elif isinstance(field.attribute_type, fd.SeasonalParameter):
            return "Sesonal_Parameter"
          elif isinstance(field.attribute_type, fd.Table):
            return "Table"


        if 'xml' not in filename[-4:]:
          filename = filename + '.xml'
        data_file = codecs.open(filename, "w", encoding="utf8")
        

        if session is None:
            raise ExportError(u"Cannot export without a session object")
        self.session = session
        assert isinstance(network, nt.Network)
        
        # Dict is for all the types to be put into, and a blank list that will take 
        # all the nodes of that particular type.
        type_dict = {}
        for node in network.nodes:
          if node.type.name not in type_dict.keys():
            type_dict[node.type.name] =[]
        # NOTES:
        # Tree structure is counterintuitive. But it's okay to keep putting in the node names,
        # don't worry about it.
        proj = network.project
        # Network name is the root tag
        net_name = network.name.replace(" ",'_')
        data_file.write("<"+net_name+">\n\t<NetworkNodes>")

        for node in network.nodes:
          type_dict[node.type.name].append(node)   

        # tester = open('C:\Users\Hos\Desktop\\tester.txt','w')
        # tester.write("%s\n\n\n%s\n\n\n"% (str(type_dict.keys()), str(type_dict.values())))
        
        for i in range(len(type_dict.keys())):
          # tester.write("%s\n\n\n%s\n" % (str(type_dict.keys()[i]),str(type_dict.values()[i])))
          tag = type_dict.keys()[i]
          data_file.write("<%s>" % (tag))
          for node in type_dict.values()[i]:
            data_file.write("\n\t\t<Node id='%s'>\n\t\t\t<Type> %s </Type>\n\t\t\t<Name> %s </Name>\n\t\t\t<NodeFields>"%( str(node.id), str(node.type.name),node.name))
            # NOTES
            # if field[i] is TS, to get dates, use node.type.fields[i].attribute_type.dates
            # for data, use data =node.getFieldValue(self.session, node.type.fields[i])
            # data.value gives the actual array of numerical values
            # Note that the actual data in the TS are held in a NumPy ndarray (like SciPy array)
            # to get the data from the array, set v_array = fval.value, then do '''for i in range(v_array.size): print v_array.flat[i]'''

            for field in node.type.fields:
              name=field.name
              ftype = get_field_type(field)
              fval = node.getFieldValue(self.session,field)
              if fval:
                fval = fval.value
              if '<' in str(fval):
                fval = (str(fval))[1:]
              if ftype != 'Time_Series':
                data_file.write('\n\t\t\t\t<%s>\n\t\t\t\t\t<Type> %s </Type>\n\t\t\t\t<Value> %s </Value>\n\t\t\t\t</%s>' %(str(name), str(ftype), str(fval), str(name)))
              else:
                if fval is not None:
                  data_file.write('\n\t\t\t\t<%s>\n\t\t\t\t\t<Type> %s </Type>' %(str(name), str(ftype)))
                  dates = field.attribute_type.dates
                  v_array = fval          # NumPy array of values for the time series
                  for i in range(len(dates)):
                    # MARK
                    # getting an IndexError here
                    # See XIE file on Desktop
                    data_file.write("\n\t\t\t\t\t<Date> \n\t\t\t\t\t\t%s\n\t\t\t\t\t\t<Value> %s </Value>\n\t\t\t\t\t</Date>" % (dates[i],v_array.flat[i-1])) 
                  data_file.write("\n\t\t\t\t</"+name+">")
                else: continue
                  
            data_file.write("\n\t\t\t\t</NodeFields>\n\t\t</Node>\n\t\t")
          data_file.write("</%s>" % (tag))
              
        data_file.write("\n</NetworkNodes>")
        # Close the root tag
        data_file.write("\n</"+net_name+">")


REGISTRY = ExporterRegistry()
REGISTRY.register(XMLExport)
logging.info("XMLExport extension registered")        
